package linker;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Properties;

import data.SimpleStatement;
import data.SimpleURI;
import data.Statement;
import data.URI;

import edu.mit.jwi.Dictionary;
import edu.mit.jwi.IDictionary;
import edu.mit.jwi.item.ISynset;
import edu.mit.jwi.item.ISynsetID;
import edu.mit.jwi.item.IWord;
import edu.mit.jwi.item.POS;
import edu.mit.jwi.item.Pointer;
import edu.mit.jwi.item.SynsetID;
import edu.mit.jwi.item.Word;

public class HyperBuilder {
	private IDictionary dict;
	private String version;
	private ArrayList<ISynset> syns;
	private HashSet<String> done;
	private DotExport ex;
	public HyperBuilder(URL wn_path) {
		dict = new Dictionary(wn_path);
		dict.open();
		version = "WN" + dict.getVersion().getMajorVersion()
				+ dict.getVersion().getMinorVersion();
		syns= new ArrayList<ISynset>();
		done= new HashSet<String>();
		ex= new DotExport();
	}
	
	public String getDictVersion()
	{
		return this.version;
	}
	
	public void add(URI uri){
		String id= "SID-"+uri.getSurfix().split("-")[1]+"-N";
		SynsetID synId= SynsetID.parseSynsetID(id);
		syns.add(dict.getSynset(synId));
	}

	public void export(FileOutputStream out)
	{
		ex.export(out);
	}
	
	public void build(FileOutputStream out,FileOutputStream out_f) throws IOException
	{

		String prefix = "http://www.ontologyportal.org/WordNet.owl";
		String prefix_f="omics";
		while(!syns.isEmpty())
		{
			ISynset s=syns.remove(0);
			if(done.contains(s.toString()))
				continue;
			for(ISynsetID oid:s.getRelatedSynsets(Pointer.HYPERNYM))
			{

				ISynset o = dict.getSynset(oid);
				boolean arti=false;
				for(ISynsetID t:o.getRelatedSynsets())
					if(t.getOffset()==21939||t.getOffset()==22119)//21939
						arti=true;
				if(!arti)
					continue;
				syns.add(o);
				SimpleStatement ret = new SimpleStatement(
						new SimpleURI(prefix, makeSurfix(s.getID().toString())),new SimpleURI(prefix,"hypernym"),
						new SimpleURI(prefix, makeSurfix(o.getID().toString())));
				out.write(ret.toString().getBytes());
				SimpleStatement ret_f = new SimpleStatement(
						new SimpleURI(prefix_f, makeSurfix1(s.getWord(1).toString())),new SimpleURI("rdfs","subClassOf"),
						new SimpleURI(prefix_f, makeSurfix1(o.getWord(1).toString())));	
				out_f.write(ret_f.toString1().getBytes());
				ex.add(s, o);
//				for(IWord ws:s.getWords())
//				{
//					for(IWord wo:o.getWords())
//					{
//						SimpleStatement ret_f = new SimpleStatement(
//								new SimpleURI(prefix_f, makeSurfix1(ws.toString())),new SimpleURI("rdfs","subClassOf"),
//								new SimpleURI(prefix_f, makeSurfix1(wo.toString())));				
//						out_f.write(ret_f.toString1().getBytes());
//					}
//				}
				
				
			}
//			for(ISynsetID oid:s.getRelatedSynsets(Pointer.HYPONYM))
//			{
//				ISynset o = dict.getSynset(oid);
//				syns.add(o);
//				SimpleStatement ret = new SimpleStatement(
//						new SimpleURI(prefix, makeSurfix(s.getID().toString())),new SimpleURI(prefix,"hyponym"),
//						new SimpleURI(prefix, makeSurfix(o.getID().toString())));
//				out.write(ret.toString().getBytes());
//
//				for(IWord ws:s.getWords())
//				{
//					for(IWord wo:o.getWords())
//					{
//						SimpleStatement ret_f = new SimpleStatement(
//								new SimpleURI(prefix_f, makeSurfix1(wo.toString())),new SimpleURI("rdfs","subClassOf"),
//								new SimpleURI(prefix_f, makeSurfix1(ws.toString())));				
//						out_f.write(ret_f.toString1().getBytes());
//					}
//				}
//			}
			done.add(s.toString());
		}
	}
	
	public static void main(String[] args) {
		
		if (args.length < 1) {
			System.out
					.println("please specify the path for config file as parameter");
			return;

		}
		String config = args[0];
		Properties pre = new Properties();
		try {
			pre.load(new FileInputStream(config));
		} catch (FileNotFoundException e) {
			System.out.println("cannot find config file");
			return;
		} catch (IOException e) {
			System.out.println("cannot open config file");
			return;
		}

		String output = pre.getProperty("output");
		String input = pre.getProperty("input");
		String wn = pre.getProperty("wordNet");
		URL url;


		
		try {
			url = new URL("file", null, wn);
		} catch (MalformedURLException e2) {
			System.out.println("invalid path");
			return;
		}

		HyperBuilder builder = new HyperBuilder(url);

		Parser par = new Parser(null);
		try {
			par.open(input);
		} catch (FileNotFoundException e) {
			System.out.println("cannot find input file");
			return;
		} catch (IOException e) {
			System.out.println("cannot open input file");
			return;
		}
		File outDir = new File(output);
		if (!outDir.exists())
			outDir.mkdir();
		else if (!outDir.isDirectory()) {
			System.out.println("output is not a directory");
			return;
		}
		File outFile;
		FileOutputStream out;
		outFile = new File(outDir, "synsethypernyms.nt");
		try {
			out = new FileOutputStream(outFile);
		} catch (FileNotFoundException e1) {
			System.out.println("cannot open out put file");
			return;
		}
		File dotFile;
		FileOutputStream dot;
		dotFile = new File(outDir, "tree.dot");
		try {
			dot = new FileOutputStream(dotFile);
		} catch (FileNotFoundException e1) {
			System.out.println("cannot open out put file");
			return;
		}
		
		File outFile_f;
		FileOutputStream out_f;
		outFile_f = new File(outDir, "synsethypernyms_fake.nt");
		try {
			out_f = new FileOutputStream(outFile_f);
		} catch (FileNotFoundException e1) {
			System.out.println("cannot open out put file");
			return;
		}
		
		
		System.out.println("processing...");

		while (par.hasNext()) {
		Statement s= par.nextStatement();
		builder.add(s.getSubject());
		builder.add(s.getObject());
		}
		try {
			builder.build(out,out_f);
			builder.export(dot);
			out.close();
			out_f.close();
		} catch (IOException e) {
			System.out.println("building IO error");
			return;
		}
		System.out.println("linking complete");
	}
	private String makeSurfix(String id) {
		return this.version + "-" + id.split("-")[1];
	}
	private String makeSurfix1(String id) {
		String[] rets=id.split("-");
		return rets[rets.length-1];
	}
}
